<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>摄像头测试</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            margin: 20px;
        }
        #video-container {
            margin: 20px 0;
        }
        video {
            border: 1px solid #ccc;
            max-width: 100%;
            background-color: #000;
        }
        button {
            padding: 10px 20px;
            margin: 5px;
            cursor: pointer;
            font-size: 16px;
            border: none;
            border-radius: 5px;
            background-color: #4CAF50;
            color: white;
        }
        button:hover {
            background-color: #45a049;
        }
        button:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
        }
        #status {
            margin-top: 20px;
            font-size: 18px;
            text-align: center;
        }
        .error {
            color: red;
        }
    </style>
</head>
<body>
    <h1>摄像头测试</h1>
    
    <div id="video-container">
        <video id="camera-feed" autoplay playsinline></video>
    </div>
    
    <div id="controls">
        <button id="start-camera">打开摄像头</button>
        <button id="stop-camera" disabled>关闭摄像头</button>
        <button id="toggle-mirror">镜像显示</button>
    </div>
    
    <div id="status"></div>
    
    <script>
        // 获取DOM元素
        const videoElement = document.getElementById('camera-feed');
        const startButton = document.getElementById('start-camera');
        const stopButton = document.getElementById('stop-camera');
        const toggleMirrorButton = document.getElementById('toggle-mirror');
        const statusElement = document.getElementById('status');
        
        // 全局变量
        let stream = null;
        let isMirrored = false;
        
        // 设置状态消息
        function setStatus(message, isError = false) {
            statusElement.textContent = message;
            statusElement.className = isError ? 'error' : '';
        }
        
        // 打开摄像头
        async function startCamera() {
            try {
                // 请求摄像头权限并获取媒体流
                stream = await navigator.mediaDevices.getUserMedia({
                    video: {
                        width: { ideal: 1280 },
                        height: { ideal: 720 },
                        facingMode: 'user' // 使用前置摄像头
                    }
                });
                
                // 将媒体流绑定到视频元素
                videoElement.srcObject = stream;
                
                // 更新UI状态
                startButton.disabled = true;
                stopButton.disabled = false;
                setStatus('摄像头已成功打开');
                
                // 监听页面卸载事件，确保释放资源
                window.addEventListener('beforeunload', stopCamera);
            } catch (error) {
                console.error('获取摄像头失败:', error);
                
                // 根据错误类型提供友好的错误信息
                let errorMessage = '无法访问摄像头';
                if (error.name === 'NotReadableError') {
                    errorMessage = '摄像头被其他应用程序占用，请关闭其他使用摄像头的应用后重试';
                } else if (error.name === 'NotFoundError') {
                    errorMessage = '未找到可用的摄像头设备';
                } else if (error.name === 'NotAllowedError') {
                    errorMessage = '用户拒绝了摄像头访问权限，请在浏览器设置中允许访问';
                } else if (error.name === 'SecurityError') {
                    errorMessage = '安全错误：无法访问摄像头，请检查浏览器安全设置';
                }
                
                setStatus(errorMessage, true);
            }
        }
        
        // 关闭摄像头并释放资源
        function stopCamera() {
            try {
                if (stream) {
                    // 停止所有媒体轨道
                    stream.getTracks().forEach(track => track.stop());
                    stream = null;
                    
                    // 清空视频元素
                    videoElement.srcObject = null;
                    
                    // 更新UI状态
                    startButton.disabled = false;
                    stopButton.disabled = true;
                    setStatus('摄像头已关闭');
                    
                    // 移除事件监听器
                    window.removeEventListener('beforeunload', stopCamera);
                }
            } catch (error) {
                console.error('关闭摄像头时出错:', error);
                setStatus('关闭摄像头时出错', true);
            }
        }
        
        // 切换镜像显示
        function toggleMirror() {
            isMirrored = !isMirrored;
            videoElement.style.transform = isMirrored ? 'scaleX(-1)' : '';
            toggleMirrorButton.textContent = isMirrored ? '取消镜像' : '镜像显示';
        }
        
        // 绑定事件监听器
        startButton.addEventListener('click', startCamera);
        stopButton.addEventListener('click', stopCamera);
        toggleMirrorButton.addEventListener('click', toggleMirror);
        
        // 页面加载时自动尝试打开摄像头（可选）
        // window.addEventListener('load', startCamera);
    </script>
</body>
</html>```

### 代码说明

这个实现具有以下特点：

1. **完整的用户界面**：包含视频显示区域和控制按钮（打开/关闭摄像头、镜像显示）

2. **健壮的错误处理**：针对不同类型的摄像头错误提供具体的错误信息（如权限拒绝、设备占用、设备未找到等）

3. **资源管理**：
   - 正确释放摄像头资源
   - 添加页面卸载事件监听，确保资源在页面关闭时被释放
   - 防止摄像头资源泄漏

4. **用户体验优化**：
   - 镜像显示功能（前置摄像头常用）
   - 按钮状态动态更新
   - 清晰的状态提示

5. **视频质量设置**：设置了理想的视频分辨率（1280x720）

你可以根据需要调整样式或功能，代码已经在原有的index.html文件基础上完全重写，确保了摄像头功能的正常实现和资源的正确管理。
